from odoo import models, fields, api, _
from odoo.exceptions import ValidationError
import logging

_logger = logging.getLogger(__name__)


class DingTalkMessage(models.Model):
    _name = 'dingtalk.message'
    _description = '钉钉消息'
    _rec_name = 'subject'
    _order = 'create_date desc'
    _inherit = ['mail.thread', 'mail.activity.mixin']
    
    subject = fields.Char(string="消息标题", required=True)
    content = fields.Text(string="消息内容", required=True)
    
    # 消息类型
    message_type = fields.Selection([
        ('work_notification', '工作通知'),
        ('org_robot', '企业内部机器人'),
        ('robot_personal', '自定义机器人（@ 个人）'),
        ('robot_group', '自定义机器人（群消息）'),
        ('group_message', '群消息'),
    ], string="消息类型", required=True, default='org_robot')
    
    # 消息格式
    msg_format = fields.Selection([
        ('text', '文本'),
        ('markdown', 'Markdown'),
        ('link', '链接'),
        ('action_card', '卡片'),
    ], string="消息格式", default='markdown')
    
    # 接收人
    recipient_ids = fields.Many2many('dingtalk.employee', string="接收人",
                                    help="接收此消息的钉钉员工")
    recipient_userids = fields.Char(string="接收人 UserID",
                                    help="钉钉 UserID，多个用逗号分隔")
    
    # 群聊
    chatid = fields.Char(string="群聊 ID", help="钉钉群聊的 chatid")
    
    # 机器人
    webhook_url = fields.Char(string="Webhook URL")
    webhook_secret = fields.Char(string="Webhook 密钥")
    
    # @ 功能
    at_mobiles = fields.Char(string="@ 手机号", help="多个手机号用逗号分隔")
    at_all = fields.Boolean(string="@ 所有人", default=False)
    
    # 发送状态
    status = fields.Selection([
        ('draft', '草稿'),
        ('sending', '发送中'),
        ('sent', '已发送'),
        ('failed', '失败'),
    ], string="状态", default='draft', tracking=True)
    
    task_id = fields.Char(string="钉钉任务ID", readonly=True,
                         help="钉钉返回的消息任务ID")
    error_message = fields.Text(string="错误信息", readonly=True)
    
    send_time = fields.Datetime(string="发送时间", readonly=True)
    
    # 链接消息专用字段
    link_url = fields.Char(string="链接URL")
    link_pic_url = fields.Char(string="图片URL")
    
    def action_send_message(self):
        """发送消息"""
        self.ensure_one()
        
        config = self.env['dingtalk.config'].get_default_config()
        access_token = config.get_valid_access_token()
        api = config._get_api_client()
        
        self.write({'status': 'sending'})
        
        try:
            result = None
            
            if self.message_type == 'work_notification':
                # 发送工作通知
                result = self._send_work_notification(api, access_token)
                
            elif self.message_type == 'org_robot':
                # 企业内部机器人消息
                result = self._send_org_robot_message(api, access_token)
                
            elif self.message_type == 'robot_personal':
                # 自定义机器人发送个人消息（实际是发送到群，然后 @ 指定人）
                result = self._send_webhook_robot_message(api)
                
            elif self.message_type == 'robot_group':
                # 自定义机器人发送群消息
                result = self._send_webhook_robot_message(api)
                
            elif self.message_type == 'group_message':
                # 发送群消息
                result = self._send_group_message(api, access_token)
            
            if result and result.get('success'):
                self.write({
                    'status': 'sent',
                    'send_time': fields.Datetime.now(),
                    'task_id': result.get('task_id', ''),
                    'error_message': False,
                })
                
                # 显示成功通知
                message = _('消息已成功发送到钉钉')
                return {
                    'type': 'ir.actions.client',
                    'tag': 'display_notification',
                    'params': {
                        'title': _('✅ 发送成功'),
                        'message': message,
                        'type': 'success',
                        'sticky': False,
                        'next': {'type': 'ir.actions.act_window', 'res_model': 'dingtalk.message', 'res_id': self.id, 'views': [[False, 'form']], 'target': 'current'},
                    }
                }
            else:
                error_msg = result.get('error', '未知错误') if result else '发送失败'
                self.write({
                    'status': 'failed',
                    'error_message': error_msg,
                })
                
                return {
                    'type': 'ir.actions.client',
                    'tag': 'display_notification',
                    'params': {
                        'title': _('发送失败'),
                        'message': _('错误: %s') % error_msg,
                        'type': 'danger',
                        'sticky': True,
                    }
                }
                
        except Exception as e:
            self.write({
                'status': 'failed',
                'error_message': str(e),
            })
            raise ValidationError(_('发送消息失败: %s') % str(e))
    
    def _send_work_notification(self, api, access_token):
        """发送工作通知"""
        # 检查 AgentID
        config = self.env['dingtalk.config'].get_default_config()
        if not config.agent_id:
            raise ValidationError(_('发送工作通知需要配置 AgentID！\n\n请在钉钉配置中填写 AgentID。\n\n获取方法：\n1. 访问 https://open-dev.dingtalk.com/\n2. 找到你的应用\n3. 在应用详情页查看 AgentId'))
        
        # 准备接收人列表
        if self.recipient_userids:
            userid_list = self.recipient_userids.split(',')
            userid_list = [uid.strip() for uid in userid_list]  # 去除空格
        elif self.recipient_ids:
            userid_list = self.recipient_ids.mapped('userid')
        else:
            raise ValidationError(_('请指定接收人'))
        
        # 准备消息内容
        if self.msg_format == 'markdown':
            msg_content = {
                'title': self.subject,
                'text': self.content
            }
        elif self.msg_format == 'link':
            msg_content = {
                'title': self.subject,
                'text': self.content,
                'messageUrl': self.link_url or '',
                'picUrl': self.link_pic_url or '',
            }
            return api.send_work_notification(access_token, userid_list, msg_content, 'link')
        else:
            msg_content = self.content
        
        return api.send_work_notification(access_token, userid_list, msg_content, self.msg_format)
    
    def _send_org_robot_message(self, api, access_token):
        """发送企业内部机器人消息"""
        config = self.env['dingtalk.config'].get_default_config()
        
        if not config.robot_code:
            raise ValidationError(_('请在钉钉配置中填写企业内部机器人的 RobotCode！\n\n获取方法：\n1. 钉钉管理后台 > 工作台 > 机器人管理\n2. 创建或找到你的企业内部机器人\n3. 复制 RobotCode'))
        
        # 准备接收人列表
        if self.recipient_userids:
            user_ids = self.recipient_userids.replace(' ', '')  # 去除空格
        elif self.recipient_ids:
            user_ids = ','.join(self.recipient_ids.mapped('userid'))
        else:
            raise ValidationError(_('请指定接收人'))
        
        # 准备消息参数（JSON 对象格式）
        import json
        import logging
        _logger = logging.getLogger(__name__)
        
        if self.msg_format == 'markdown':
            # Markdown 格式 - 使用 text 字段（会显示纯文本，不渲染 Markdown）
            # 钉钉企业内部机器人的 Markdown 支持有限
            msg_param = {
                "text": f"**{self.subject}**\n\n{self.content}",
                "title": self.subject
            }
            msg_key = 'sampleMarkdown'
            _logger.info(f"📝 Markdown 消息参数: {msg_param}")
        else:
            # 纯文本格式 - 使用 content 字段
            msg_param = {
                "content": self.content
            }
            msg_key = 'sampleText'
            _logger.info(f"📝 文本消息参数: {msg_param}")
        
        # 发送单聊消息
        return api.send_org_robot_message(
            access_token=access_token,
            robot_code=config.robot_code,
            user_ids=user_ids,
            msg_param=msg_param,
            msg_key=msg_key
        )
    
    def _send_webhook_robot_message(self, api):
        """通过自定义机器人（Webhook）发送消息"""
        if not self.webhook_url or not self.webhook_secret:
            raise ValidationError(_('请配置机器人 Webhook URL 和密钥'))
        
        # 准备消息内容
        if self.msg_format == 'markdown':
            content = {
                'title': self.subject,
                'text': self.content
            }
        else:
            content = self.content
        
        # 准备 @ 列表
        at_mobiles = self.at_mobiles.split(',') if self.at_mobiles else None
        
        return api.send_robot_message(
            webhook_url=self.webhook_url,
            secret=self.webhook_secret,
            content=content,
            msg_type=self.msg_format,
            at_mobiles=at_mobiles,
            at_all=self.at_all
        )
    
    def _send_group_message(self, api, access_token):
        """发送群消息"""
        if not self.chatid:
            raise ValidationError(_('请指定群聊 ID'))
        
        return api.send_group_message(
            access_token=access_token,
            chatid=self.chatid,
            content=self.content,
            msg_type=self.msg_format
        )
    
    @api.model
    def send_notification(self, subject, content, recipient_userids=None, recipient_ids=None, msg_format='markdown'):
        """快捷方法：创建并发送工作通知"""
        vals = {
            'subject': subject,
            'content': content,
            'message_type': 'work_notification',
            'msg_format': msg_format,
        }
        
        if recipient_userids:
            vals['recipient_userids'] = ','.join(recipient_userids) if isinstance(recipient_userids, list) else recipient_userids
        
        if recipient_ids:
            vals['recipient_ids'] = [(6, 0, recipient_ids)]
        
        message = self.create(vals)
        message.action_send_message()
        
        return message
    
    @api.model
    def send_robot_notification(self, webhook_url, secret, title, content, at_mobiles=None):
        """快捷方法：通过机器人发送消息"""
        vals = {
            'subject': title,
            'content': content,
            'message_type': 'robot_group',
            'msg_format': 'markdown',
            'webhook_url': webhook_url,
            'webhook_secret': secret,
            'at_mobiles': ','.join(at_mobiles) if at_mobiles else False,
        }
        
        message = self.create(vals)
        message.action_send_message()
        
        return message

